/**
  ******************************************************************************
  * @file    usart.c
  * @brief   This file provides code for the configuration
  *          of the USART instances.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "usart.h"
#include "protocal.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */

UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;

uint8_t g_Usart1RxBuf[UART_RX_BUF_LEN];
uint8_t g_Usart2RxBuf[UART_RX_BUF_LEN];

void Rs485_WriteDisable(void);

/* USART1 init function */

void Usart1_Init(uint32_t baudRate)
{
	huart1.Instance = USART1;
	huart1.Init.BaudRate = baudRate;
	huart1.Init.WordLength = UART_WORDLENGTH_8B;
	huart1.Init.StopBits = UART_STOPBITS_1;
	huart1.Init.Parity = UART_PARITY_NONE;
	huart1.Init.Mode = UART_MODE_TX_RX;
	huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart1.Init.OverSampling = UART_OVERSAMPLING_16;
	huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
	huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
	if (HAL_UART_Init(&huart1) != HAL_OK)
	{
		Error_Handler();
	}
	HAL_UART_Receive_DMA(&huart1,g_Usart1RxBuf,UART_RX_BUF_LEN);
	Rs485_WriteDisable();
}
/* USART2 init function */

void Rs485_GpioInit(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;

	__HAL_RCC_GPIOA_CLK_ENABLE();
	GPIO_InitStruct.Pin = RS485_ENABLE_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
	HAL_GPIO_Init(RS485_ENABLE_PORT, &GPIO_InitStruct);
	HAL_GPIO_WritePin(RS485_ENABLE_PORT, RS485_ENABLE_PIN, GPIO_PIN_RESET);
}

void Rs485_WriteEnable(void)
{
	HAL_GPIO_WritePin(RS485_ENABLE_PORT, RS485_ENABLE_PIN, GPIO_PIN_SET);
}

void Rs485_WriteDisable(void)
{
	HAL_GPIO_WritePin(RS485_ENABLE_PORT, RS485_ENABLE_PIN, GPIO_PIN_RESET);
}

void Usart2_Init(uint32_t baudRate)
{
	huart2.Instance = USART2;
	huart2.Init.BaudRate = baudRate;
	huart2.Init.WordLength = UART_WORDLENGTH_8B;
	huart2.Init.StopBits = UART_STOPBITS_1;
	huart2.Init.Parity = UART_PARITY_NONE;
	huart2.Init.Mode = UART_MODE_TX_RX;
	huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart2.Init.OverSampling = UART_OVERSAMPLING_16;
	huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
	huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
	if (HAL_UART_Init(&huart2) != HAL_OK)
	{
		Error_Handler();
	}
	HAL_UART_Receive_DMA(&huart2,g_Usart2RxBuf,UART_RX_BUF_LEN);

	Rs485_GpioInit();
	Rs485_WriteDisable();
}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};

	if(uartHandle->Instance==USART1)
	{
		/* USER CODE BEGIN USART1_MspInit 0 */

		/* USER CODE END USART1_MspInit 0 */
		/* USART1 clock enable */
		__HAL_RCC_USART1_CLK_ENABLE();

		__HAL_RCC_GPIOA_CLK_ENABLE();
        __HAL_RCC_DMA1_CLK_ENABLE();
		/**USART1 GPIO Configuration
		PA9     ------> USART1_TX
		PA10     ------> USART1_RX
		*/
		GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
		GPIO_InitStruct.Pull = GPIO_NOPULL;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
		GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
		HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

		/* USER CODE BEGIN USART1_MspInit 1 */

		hdma_usart1_rx.Instance = DMA1_Channel5;
		hdma_usart1_rx.Init.Request = DMA_REQUEST_2;
		hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
		hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
		hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
		hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
		hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
		hdma_usart1_rx.Init.Mode = DMA_NORMAL;
		hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
		HAL_DMA_Init(&hdma_usart1_rx);

		__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);

		/* USART3_TX Init */
		hdma_usart1_tx.Instance = DMA1_Channel4;
		hdma_usart1_tx.Init.Request = DMA_REQUEST_2;
		hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
		hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
		hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
		hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
		hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
		hdma_usart1_tx.Init.Mode = DMA_NORMAL;
		hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
		HAL_DMA_Init(&hdma_usart1_tx);

		__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);

		/* DMA1_Channel2_IRQn interrupt configuration */
		//HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
		//HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
		/* DMA1_Channel3_IRQn interrupt configuration */
		HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 1, 0);
		HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);

		/* USER CODE BEGIN USART3_MspInit 1 */
		HAL_NVIC_SetPriority(USART1_IRQn, 1, 0);
		HAL_NVIC_EnableIRQ(USART1_IRQn);

		uartHandle->Instance->CR1 |= USART_CR1_IDLEIE;
		uartHandle->Instance->CR1 &= ~USART_CR1_RXNEIE;
		/* USER CODE END USART1_MspInit 1 */
	}
	else if(uartHandle->Instance==USART2)
	{
		__HAL_RCC_DMA1_CLK_ENABLE();
		__HAL_RCC_USART2_CLK_ENABLE();

		__HAL_RCC_GPIOA_CLK_ENABLE();
		/**USART3 GPIO Configuration    
		PB10     ------> USART3_TX
		PB11     ------> USART3_RX 
		*/
		GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
		GPIO_InitStruct.Pull = GPIO_NOPULL;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
		GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
		HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

		hdma_usart2_rx.Instance = DMA1_Channel6;
		hdma_usart2_rx.Init.Request = DMA_REQUEST_2;
		hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
		hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
		hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
		hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
		hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
		hdma_usart2_rx.Init.Mode = DMA_NORMAL;
		hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
		HAL_DMA_Init(&hdma_usart2_rx);

		__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);

		/* USART3_TX Init */
		hdma_usart2_tx.Instance = DMA1_Channel7;
		hdma_usart2_tx.Init.Request = DMA_REQUEST_2;
		hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
		hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
		hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
		hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
		hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
		hdma_usart2_tx.Init.Mode = DMA_NORMAL;
		hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
		HAL_DMA_Init(&hdma_usart2_tx);

		__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart2_tx);

		/* DMA1_Channel2_IRQn interrupt configuration */
		//HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
		//HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
		/* DMA1_Channel3_IRQn interrupt configuration */
		HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 1, 0);
		HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);

		/* USER CODE BEGIN USART3_MspInit 1 */
		HAL_NVIC_SetPriority(USART2_IRQn, 1, 0);
		HAL_NVIC_EnableIRQ(USART2_IRQn);

		uartHandle->Instance->CR1 |= USART_CR1_IDLEIE;
		uartHandle->Instance->CR1 &= ~USART_CR1_RXNEIE;
	}
}

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{

  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspDeInit 0 */

  /* USER CODE END USART1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART1_CLK_DISABLE();

    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);

  /* USER CODE BEGIN USART1_MspDeInit 1 */

  /* USER CODE END USART1_MspDeInit 1 */
  }
  else if(uartHandle->Instance==USART2)
  {
  /* USER CODE BEGIN USART2_MspDeInit 0 */

  /* USER CODE END USART2_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART2_CLK_DISABLE();

    /**USART2 GPIO Configuration
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);

    /* USART2 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART2_IRQn);
  /* USER CODE BEGIN USART2_MspDeInit 1 */

  /* USER CODE END USART2_MspDeInit 1 */
  }
}

void Usart1_SendData(uint8_t *pData, uint16_t length)
{
	Rs485_WriteEnable();
	while(length--)
	{
		HAL_UART_Transmit(&huart1,pData,1,1000);
		pData++;

	}

	Rs485_WriteDisable();
    //    HAL_Delay(10);
}

void Usart2_SendData(uint8_t *pData, uint16_t length)
{	
	Rs485_WriteEnable();
	while(length--)
	{
		HAL_UART_Transmit(&huart2,pData,1,1000);
		pData++;
	}
	Rs485_WriteDisable();
}

void USART1_IRQHandler(void)
{
	uint32_t length = 0;
	length = length;

	HAL_UART_IRQHandler(&huart1);
	if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) == SET)
	{
		__HAL_UART_CLEAR_IDLEFLAG(&huart1);

		HAL_UART_DMAStop(&huart1);
		length = UART_RX_BUF_LEN - huart1.hdmarx->Instance->CNDTR;

		Mb_ProtocalAnalysis(g_Usart1RxBuf, length);

		HAL_UART_Receive_DMA(&huart1, g_Usart1RxBuf, UART_RX_BUF_LEN);
	}
}

void USART2_IRQHandler(void)
{
	uint32_t length = 0;
	length = length;

	HAL_UART_IRQHandler(&huart2);
	if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) == SET)
	{
		__HAL_UART_CLEAR_IDLEFLAG(&huart2);

		HAL_UART_DMAStop(&huart2);
		length = UART_RX_BUF_LEN - huart2.hdmarx->Instance->CNDTR;

		Mb_ProtocalAnalysis(g_Usart2RxBuf, length);
        
		HAL_UART_Receive_DMA(&huart2, g_Usart2RxBuf, UART_RX_BUF_LEN);
	}
}

/* USER CODE BEGIN 1 */
#ifdef __GNUC__

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

PUTCHAR_PROTOTYPE
{
#if (FACT_CHOOSE == C7_V2)
	HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
#elif (FACT_CHOOSE == WANWAN)
	HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
#endif
  return ch;
}
#endif

int _write(int file, char *ptr, int len)
{
      int DataIdx;

      for (DataIdx = 0; DataIdx < len;DataIdx++)
     {
           __io_putchar(*ptr++);
     }
      return len;
}

/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
